package com.shop.cereshop.app.service.product.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.shop.cereshop.app.dao.product.CereProductSkuDAO;
import com.shop.cereshop.app.dao.product.CereShopProductDAO;
import com.shop.cereshop.app.dao.product.CereSkuNameDAO;
import com.shop.cereshop.app.dao.product.SkuProjectDAO;
import com.shop.cereshop.app.domain.shop.CustomerServiceDTO;
import com.shop.cereshop.app.page.product.ProductCoupon;
import com.shop.cereshop.app.page.product.ProductListVO;
import com.shop.cereshop.app.page.productDetail.*;
import com.shop.cereshop.app.param.product.ProductDTO;
import com.shop.cereshop.app.param.product.ProductListParam;
import com.shop.cereshop.app.param.product.QueryProductListDTO;
import com.shop.cereshop.app.param.product.SearchProductParam;
import com.shop.cereshop.app.service.activity.CerePlatformActivityService;
import com.shop.cereshop.app.service.buyer.CereBuyerReceiveService;
import com.shop.cereshop.app.service.collect.CereBuyerCollectService;
import com.shop.cereshop.app.service.coupon.CereShopCouponService;
import com.shop.cereshop.app.service.product.ShopProductV2Service;
import com.shop.cereshop.app.service.redis.LabelService;
import com.shop.cereshop.app.utils.BusinessUtils;
import com.shop.cereshop.commons.constant.CoReturnFormat;
import com.shop.cereshop.commons.constant.IntegerEnum;
import com.shop.cereshop.commons.domain.calculate.Calculate;
import com.shop.cereshop.commons.domain.collect.CereBuyerCollect;
import com.shop.cereshop.commons.domain.product.SkuProject;
import com.shop.cereshop.commons.exception.CoBusinessException;
import com.shop.cereshop.commons.result.Result;
import com.shop.cereshop.commons.utils.EmptyUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class ShopProductV2ServiceImpl implements ShopProductV2Service {

    private final CereShopProductDAO cereShopProductDAO;
    private final CereProductSkuDAO cereProductSkuDAO;
    private final CereSkuNameDAO skuNameDAO;
    private final SkuProjectDAO skuProjectDAO;
    private final ProductAsyncService productAsyncService;
    private final CereBuyerReceiveService cereBuyerReceiveService;
    private final CereBuyerCollectService cereBuyerCollectService;
    private final CerePlatformActivityService cerePlatformActivityService;
    private final CereShopCouponService cereShopCouponService;
    private final LabelService labelService;

    @Override
    public PageInfo<ProductListVO> getShopProductPage(ProductListParam param) throws CoBusinessException {
        if (param == null || param.getShopId() == null) {
            throw new CoBusinessException(CoReturnFormat.PARAM_INVALID);
        }
        PageHelper.startPage(param.getPage(), param.getPageSize());
        QueryProductListDTO queryDTO = new QueryProductListDTO()
                .setShopId(param.getShopId())
                .setShopType(param.getShopType())
                .setCityCode(param.getCityCode())
                .setSort(param.getSort());
        List<ProductListVO> products = cereShopProductDAO.queryProductList(queryDTO);
        if (CollUtil.isEmpty(products)) {
            log.info("未查询到商品，shopId: {}", param.getShopId());
            return new PageInfo<>();
        }

        processProductAndShopLabels(products);
        return new PageInfo<>(products);
    }

    @Override
    public PageInfo<ProductListVO> searchProductList(SearchProductParam param) {
        PageHelper.startPage(param.getPage(), param.getPageSize());
        QueryProductListDTO queryDTO = new QueryProductListDTO()
                .setShopId(param.getShopId())
                .setProductName(param.getKeyword())
                .setShopType(param.getShopType())
                .setCityCode(param.getCityCode())
                .setSort(param.getSortType())
                .setClassifyId(param.getClassifyId());
        List<ProductListVO> products = cereShopProductDAO.queryProductList(queryDTO);
        if (CollUtil.isEmpty(products)) {
            log.info("未查询到商品，keyword: {}", param.getKeyword());
            return new PageInfo<>();
        }

        processProductAndShopLabels(products);
        return new PageInfo<>(products);
    }

    @Override
    public PageInfo<ProductListVO> getUserCollectProductList(SearchProductParam param) {
        PageHelper.startPage(param.getPage(), param.getPageSize());
        QueryProductListDTO queryDTO = new QueryProductListDTO()
                .setShopId(param.getShopId())
                .setProductName(param.getKeyword())
                .setShopType(param.getShopType())
                .setCityCode(param.getCityCode())
                .setSort(param.getSortType())
                .setClassifyId(param.getClassifyId())
                .setBuyerUserId(param.getBuyerUserId());

        List<ProductListVO> products = cereShopProductDAO.getUserCollectProductList(queryDTO);
        if (CollUtil.isEmpty(products)) {
            log.info("未查询到商品，keyword: {}", param.getKeyword());
            return new PageInfo<>();
        }

        processProductAndShopLabels(products);
        return new PageInfo<>(products);
    }

    /**
     * 处理商品和店铺标签
     *
     * @param products 商品列表
     */
    private void processProductAndShopLabels(List<ProductListVO> products) {
        List<Long> productIds = products.stream().map(ProductListVO::getProductId).collect(Collectors.toList());
        Map<Long, Calculate> labelMap = labelService.getProductLabelMap(productIds);

        List<Long> shopIds = products.stream().map(ProductListVO::getShopId).distinct().collect(Collectors.toList());
        Map<Long, Calculate> serviceLabelMap = labelService.getShopServiceLabelMap(shopIds);

        for (ProductListVO product : products) {
            Calculate productCalculate = labelMap.get(product.getProductId());
            product.setProductLabels(BusinessUtils.getProductLabels(productCalculate));

            Calculate shopCalculate = serviceLabelMap.get(product.getShopId());
            product.setShopLabels(BusinessUtils.getShopServiceLabels(shopCalculate));

            product.setShopType(product.getProductType());
        }
    }

    @Override
    public Result<List<ProductListVO>> productHotList(String cityCode) {
        List<ProductListVO> productHotList = cereShopProductDAO.getProductHotList(cityCode);
        if (CollUtil.isEmpty(productHotList)) {
            log.warn("没有查询到热门商品数据");
            return Result.success(Collections.emptyList());
        }
        for (ProductListVO product : productHotList) {
            product.setShopType(product.getProductType());
        }
        return Result.success(productHotList);
    }

    @Override
    public ShopProductDetailVO getProductDetail(ProductDTO param, Long buyerUserId) throws Exception {
        Long shopId = cereShopProductDAO.getShopId(param.getProductId());
        if (shopId == null) {
            throw new CoBusinessException(CoReturnFormat.MERCHANT_NOT_EXIST);
        }
        param.setShopId(shopId);
        // 如果已登录、记录用户行为信息
        if (buyerUserId != null) {
            productAsyncService.addProductVisit(param, buyerUserId);
        }
        // 更新日度统计
        productAsyncService.addProductStats(param);

        // 查询商品详情数据（根据是否查询实时信息表字段确定查询方式）
        ShopProductDetailVO detailVO = cereShopProductDAO.getProductDetailById(param.getProductId(), shopId);
        if (detailVO == null) {
            throw new CoBusinessException(CoReturnFormat.PRODUCT_NOT_EXISTS);
        }
        detailVO.setFinalSales(detailVO.getSalesVolume() + detailVO.getFictitiousNumber());

        detailVO.setShopType(detailVO.getProductType());

        // 处理营业时间
        // processShopWeeks(detailVO);

        // 查询商品图片
        detailVO.setImages(cereShopProductDAO.findImages(param.getProductId()));

        // 查询该商品所有组合规格数据封装到map
        processProductSkus(detailVO, param.getProductId());

        // 收货地址、商品收藏等用户相关信息
        processUserRelatedInfo(detailVO, buyerUserId);

        // 处理优惠券信息
        // processCoupons(detailVO, buyerUserId);

        //商品标签
        Calculate calculate = labelService.getProductLabel(param.getProductId());
        detailVO.setProductLabels(BusinessUtils.getProductLabels(calculate));

        detailVO.setCustomerService(new CustomerServiceDTO());

        return detailVO;
    }

    /**
     * 处理商品规格信息
     *
     * @param detailVO 商品详情数据
     * @param productId 商品ID
     */
    private void processProductSkus(ShopProductDetailVO detailVO, Long productId) {
        // 获取基础 SKU 数据
        List<SkuBaseVO> baseList = cereProductSkuDAO.findSkuBaseList(productId);
        if (CollUtil.isEmpty(baseList)) {
            return;
        }

        // 获取 SKU 规格名称-值对
        List<SkuNameVO> nameList = skuNameDAO.findSkuNameList(productId);

        // 构建 specMap（按 skuId 聚合规格）和 specGroup（按规格名分组值）
        Map<Long, Map<String, String>> specMap = new HashMap<>();
        Map<String, Set<String>> specGroup = new LinkedHashMap<>();

        for (SkuNameVO name : nameList) {
            specMap.computeIfAbsent(name.getSkuId(), k -> new LinkedHashMap<>()).put(name.getSkuName(), name.getSkuValue());
            specGroup.computeIfAbsent(name.getSkuName(), k -> new LinkedHashSet<>()).add(name.getSkuValue());
        }

        // 构建 FullSkuVO 列表（含完整规格）
        List<FullSkuVO> fullSkus = new ArrayList<>(baseList.size());
        for (SkuBaseVO base : baseList) {
            FullSkuVO full = new FullSkuVO();
            full.setSkuId(base.getSkuId());
            full.setPrice(base.getPrice());
            full.setStockNumber(base.getStockNumber());
            full.setImage(base.getSkuImage());
            // 安全获取 specs，防止 null
            Map<String, String> specs = specMap.get(base.getSkuId());
            full.setSpecs(specs != null ? specs : Collections.emptyMap());
            fullSkus.add(full);
        }

        // 构建 specifications（前端规格面板）
        List<SpecificationDTO> specifications = specGroup.entrySet().stream()
                .map(entry -> {
                    SpecificationDTO dto = new SpecificationDTO();
                    dto.setName(entry.getKey());
                    dto.setValues(new ArrayList<>(entry.getValue()));
                    return dto;
                })
                .collect(Collectors.toList());

        // 构建 skus
        int skuCount = fullSkus.size();
        List<SkuDTO> skus = new ArrayList<>(skuCount);
        List<Long> skuIds = fullSkus.stream().map(FullSkuVO::getSkuId).collect(Collectors.toList());
        Map<Long, List<SkuProject>> skuProjectMap = getSkuProjectMap(skuIds);
        for (FullSkuVO full : fullSkus) {
            SkuDTO dto = new SkuDTO();
            dto.setSkuId(full.getSkuId());
            dto.setCombinationKey(buildSkuKey(full.getSpecs()));
            dto.setPrice(full.getPrice());
            dto.setStock(full.getStockNumber() != null ? full.getStockNumber() : 0L);
            dto.setImages(StringUtils.isNotBlank(full.getImage())
                    ? Collections.singletonList(full.getImage())
                    : detailVO.getImages());
            dto.setProjects(skuProjectMap.getOrDefault(full.getSkuId(), Collections.emptyList()));
            skus.add(dto);
        }

        // 设置结果到 VO
        detailVO.setSpecifications(specifications);
        detailVO.setSkus(skus);
    }

    /**
     * 根据规格 Map 生成标准化的组合 key（按规格名排序，确保一致性）
     */
    private String buildSkuKey(Map<String, String> specs) {
        if (specs == null || specs.isEmpty()) {
            return "";
        }
        return specs.entrySet().stream()
                // 关键：保证顺序一致
                .sorted(Map.Entry.comparingByKey())
                .map(entry -> entry.getKey() + ":" + entry.getValue())
                .collect(Collectors.joining(","));
    }

    /**
     * 处理用户相关信息
     */
    private void processUserRelatedInfo(ShopProductDetailVO detailVO, Long buyerUserId) {
        if (buyerUserId != null) {
            // 查询最新收货地址数据
            // detailVO.setReceive(cereBuyerReceiveService.findlatelyReceiveByUserId(buyerUserId));
            // 查询该商品收藏状态
            CereBuyerCollect collect = cereBuyerCollectService.findByUserProduct(buyerUserId, detailVO.getProductId());
            if (collect != null) {
                detailVO.setIsCollect(collect.getState());
                detailVO.setCollectId(collect.getCollectId());
            }
        }
    }

    /**
     * 获取sku附加项目
     */
    private Map<Long, List<SkuProject>> getSkuProjectMap(List<Long> skuIds) {
        if (CollUtil.isEmpty(skuIds)) {
            return new HashMap<>();
        }

        List<SkuProject> skuProjects = skuProjectDAO.selectList(
                new QueryWrapper<SkuProject>().in("sku_id", skuIds)
        );
        if (skuProjects == null) {
            return new HashMap<>();
        }

        // 创建 skuId 到 projects 的映射
        return skuProjects.stream().collect(Collectors.groupingBy(SkuProject::getSkuId));
    }


    /**
     * 处理优惠券信息
     */
    private void processCoupons(ShopProductDetailVO detailVO, Long buyerUserId) {
        // 查询平台优惠券
        List<ProductCoupon> platformCoupons = getPlatformCoupons(buyerUserId, detailVO);

        // 查询店铺优惠券
        List<ProductCoupon> shopCoupons = getShopCoupons(buyerUserId, detailVO);

        // 格式化优惠券内容
        formatCouponContent(platformCoupons, true);
        formatCouponContent(shopCoupons, false);

        // 拼接优惠券信息
        StringBuilder couponSplicing = new StringBuilder();
        if (CollUtil.isNotEmpty(platformCoupons)) {
            couponSplicing.append(platformCoupons.stream().map(ProductCoupon::getContent).collect(Collectors.joining(";")));
        }

        if (CollUtil.isNotEmpty(shopCoupons)) {
            if (couponSplicing.length() > 0) {
                couponSplicing.append(";");
            }
            couponSplicing.append(shopCoupons.stream().map(ProductCoupon::getContent).collect(Collectors.joining(";")));
        }

        detailVO.setCouponSplicing(couponSplicing.toString());
    }

    /**
     * 格式化优惠券内容
     */
    private void formatCouponContent(List<ProductCoupon> coupons, boolean isPlatform) {
        if (EmptyUtils.isEmpty(coupons)) {
            return;
        }

        coupons.forEach(coupon -> {
            Integer discountMode = isPlatform ? coupon.getDiscountMode() : coupon.getCouponType();
            if (IntegerEnum.COUPON_TYPE_REDUTION.getCode().equals(discountMode)) {
                coupon.setContent("满" + coupon.getFullMoney().stripTrailingZeros().toPlainString() +
                        "减" + coupon.getReduceMoney().stripTrailingZeros().toPlainString() + "元");
            } else {
                coupon.setContent(coupon.getReduceMoney().stripTrailingZeros().toPlainString() + "折券");
            }
        });
    }

    /**
     * 平台优惠券信息
     */
    private List<ProductCoupon> getPlatformCoupons(Long buyerUserId, ShopProductDetailVO detail) {
        List<ProductCoupon> platformCoupons;

        if (buyerUserId != null) {
            // 过滤已使用和已过期的优惠券
            platformCoupons = cerePlatformActivityService.findCouponByProductIdAndUserId(buyerUserId, detail.getProductId());
        } else {
            platformCoupons = cerePlatformActivityService.findCouponByProductId(detail.getProductId());
        }
        // 设置活动图片数组
        if (CollUtil.isNotEmpty(platformCoupons)) {
            detail.setCouponImages(platformCoupons.stream().map(ProductCoupon::getImage).distinct().collect(Collectors.toList()));
        }
        detail.setPlatformCoupons(platformCoupons);
        return platformCoupons;
    }

     /**
      * 店铺优惠券信息
      */
    private List<ProductCoupon> getShopCoupons(Long buyerUserId, ShopProductDetailVO detail) {
        List<ProductCoupon> shopCoupons;

        if (buyerUserId != null) {
            shopCoupons = cereShopCouponService.findByProductIdAndUserId(buyerUserId, detail.getShopId(), detail.getProductId());
        } else {
            shopCoupons = cereShopCouponService.findByProductId(detail.getShopId(), detail.getProductId());
        }
        detail.setShopCoupons(shopCoupons);
        return shopCoupons;
    }

}
